#include "ACEDetectorConstruction.hh"
#include "ACEPhysicsList.hh"
#include "ACEPrimaryGeneratorAction.hh"
#include "ACEUserStackingAction.hh"
#include "ACEUserEventAction.hh"
#include "ACEUserRunAction.hh"
#include "ACEMessenger.hh"

#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "G4VisExecutive.hh"
#include "G4UIExecutive.hh"
#include "globals.hh"

#include "fstream"
using namespace std;

ACEMessenger* messenger = new ACEMessenger();

int main(int argc, char** argv) {
	G4RunManager* runningMan = new G4RunManager();

	ACEDetectorConstruction* construction = new ACEDetectorConstruction();
	runningMan->SetUserInitialization(construction);

	ACEPhysicsList* physicsList = new ACEPhysicsList();
	runningMan->SetUserInitialization(physicsList);

	ACEPrimaryGeneratorAction* PGA = new ACEPrimaryGeneratorAction();
	runningMan->SetUserAction(PGA);

//	ACEUserStackingAction* USA = new ACEUserStackingAction();
//	runningMan->SetUserAction(USA);

	ACEUserEventAction* UEA = new ACEUserEventAction();
	runningMan->SetUserAction(UEA);

	ACEUserRunAction* URA = new ACEUserRunAction();
	runningMan->SetUserAction(URA);

	G4VisManager* visMan = new G4VisExecutive();
	visMan->SetVerboseLevel(0);
	visMan->Initialize();

	runningMan->Initialize();

	G4UImanager *UIman = G4UImanager::GetUIpointer();

// Give batch file path as single argument to ACE, and it will execute it,
// otherwise, it will open a standard UI session

	if (argc > 1) {
		G4String batchPath = argv[1];
		UIman->ApplyCommand("/control/execute " + batchPath);

		if (argc > 2) {
			ofstream file(argv[2]);

			//	cout << messenger->GetAverageNumHits() << endl;

			//	int* spectrum = messenger->getSpectrum();
			//	for(int i = 0;i < 200;i++)
			//		file << i << "\t" << spectrum[i] << endl;

			double** spec = messenger->getSpaceSpectrum();
			for (int i = 0; i < messenger->getNumEvents(); i++) {
				file << spec[i][0] / cm << "\t" << spec[i][1] / cm << "\t"
						<< spec[i][2] << endl;
			}

			file.close();
		}
	} else {
		G4UIExecutive* uiExec = new G4UIExecutive(argc, argv);
		UIman->ApplyCommand("/control/execute macro/QT_Init.mac");
		uiExec->SessionStart();
		delete uiExec;
	}

	delete visMan;
	delete runningMan;

	return 0;
}
